package ar.edu.unrn.lia.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;

import org.primefaces.event.SelectEvent;

import ar.edu.unrn.lia.bean.datamodel.LazyAlquilerDataModel;
import ar.edu.unrn.lia.model.Alquiler;
import ar.edu.unrn.lia.model.AlquilerPeriodo;
import ar.edu.unrn.lia.model.Garante;
import ar.edu.unrn.lia.model.Inquilino;
import ar.edu.unrn.lia.service.AlquilerService;
import ar.edu.unrn.lia.service.GaranteService;
import ar.edu.unrn.lia.service.InquilinoService;
import ar.edu.unrn.lia.service.PropiedadService;
import ar.edu.unrn.lia.service.exception.BusinessException;
import ar.edu.unrn.lia.util.MailBusness;
import ar.edu.unrn.lia.util.MensajesAplicacion;

@ManagedBean(name = "alquilerBean")
@ViewScoped
public class AlquilerBean extends GenericBean<Alquiler> implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6741809141622602428L;

	private Long idPropiedad;

	@ManagedProperty(value = "#{alquilerService}")
	AlquilerService entityService;

	@ManagedProperty(value = "#{propiedadService}")
	PropiedadService propiedadService;

	@ManagedProperty(value = "#{inquilinoService}")
	InquilinoService inquilinoService;
	
	@ManagedProperty(value = "#{garanteService}")
	GaranteService garanteService;

	@ManagedProperty(value = "#{mailBusness}")
	MailBusness mailBusness;

	public MailBusness getMailBusness() {
		return mailBusness;
	}

	public void setMailBusness(MailBusness mailBusness) {
		this.mailBusness = mailBusness;
	}
	
	

	public GaranteService getGaranteService() {
		return garanteService;
	}

	public void setGaranteService(GaranteService garanteService) {
		this.garanteService = garanteService;
	}

	public String create() {
		setEntity(new Alquiler());
		return REDIRECT_CREATE;
	}

	public void onRowSelect(SelectEvent event) {
		agregarMensaje(FacesMessage.SEVERITY_INFO, "Alquiler Seleccionado:",
				((Alquiler) event.getObject()).getPropiedad()
						.direccionCompleta());
	}

	public String update() {
		try {
			if (getEntity().getId() == null) {
				entityService.save(getEntity());
				// TODO Email Al propietario
				getMailBusness().sendMail(
						MensajesAplicacion.getString("application.mail"),
						getEntity().getPropiedad().getPropietario().getMail(),
						"Su propiedad ha sido Alquilada",
						"Su propiedad ubicada en: "
								+ getEntity().getPropiedad()
										.direccionCompleta()
								+ " ha sido alquilada.");
				mensajeFlash("Crear Alquiler", "Operación realizada con exito.");

			} else {
				entityService.update(getEntity());
				mensajeFlash("Modificar Alquiler",
						"Operación realizada con exito.");
			}
			return REDIRECT_SEARCH;
		} catch (BusinessException e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR,
					"Se produjo un error al guardar el alquiler:",
					e.getMessage());
			return null;
		} catch (OptimisticLockException e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR, "Bloqueo",
					"Alquien modifico este Alquiler, reconsulte.");
			return null;
		} catch (Exception e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR,
					"Se produjo un error al guardar el alquiler:",
					e.getMessage());
			return null;
		}
	}

	public String delete(Alquiler entity) {
		try {

			entityService.delete(entity);
			mensajeFlash("Eliminar Alquiler", "Operación realizada con exito.");
			return REDIRECT_SEARCH;
		} catch (OptimisticLockException e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR, "Bloqueo",
					"Alquien modificó este Alquiler, reconsulte.");
			return null;
		} catch (PersistenceException e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR, "Eliminar Alquiler",
					"El Rol esta asociada a un Pagos.");
			return null;
		} catch (Exception e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR, "Eliminar Alquiler",
					e.getMessage());
			return null;
		}
	}

	@PostConstruct
	public void init() {
		setModelLazy(new LazyAlquilerDataModel(entityService));		
	}

	public List<Alquiler> getAlquilers() {
		return entityService.getAll();
	}

	public Long getIdPropiedad() {
		return idPropiedad;
	}

	public void setIdPropiedad(Long idPropiedad) {
		this.idPropiedad = idPropiedad;
	}

	public void inicio() {
		if (!FacesContext.getCurrentInstance().isPostback()) {
			if (getId() != null) {
				setEntity(entityService.getEntityById(getId()));
			} else {
				setEntity(new Alquiler());
			}
			if (getIdPropiedad() != null) {
				setEntity(new Alquiler(
						propiedadService.getEntityById(getIdPropiedad())));
			}
		}
	}

	public List<Inquilino> inquilinos(String query) {
		return getInquilinoService().findByQuery(query, "apellido", "desc");
	}
	
	public List<Garante> garantes(String query) {
		return getGaranteService().findByQuery(query, "apellido", "desc");
	}

	public void agregarPediodo() {
		getEntity().addPeriodo(new AlquilerPeriodo(1, 12, 0));
	}

	public AlquilerService getEntityService() {
		return entityService;
	}

	public void setEntityService(AlquilerService entityService) {
		this.entityService = entityService;
	}

	public PropiedadService getPropiedadService() {
		return propiedadService;
	}

	public void setPropiedadService(PropiedadService propiedadService) {
		this.propiedadService = propiedadService;
	}

	public InquilinoService getInquilinoService() {
		return inquilinoService;
	}

	public void setInquilinoService(InquilinoService inquilinoService) {
		this.inquilinoService = inquilinoService;
	}

	public List<Alquiler> alquileresProximoVencer() {

		List<Alquiler> resultado = new ArrayList<Alquiler>(0);
		try {
			resultado = getEntityService().alquileresProximoVencer();
			if (resultado.size() == 0)
				agregarMensaje(FacesMessage.SEVERITY_INFO,
						"Alquileres proximos a Vencer",
						"No hay Alquileres Proximos a Vencer");
		} catch (Exception e) {
			agregarMensaje(FacesMessage.SEVERITY_INFO, "Error Consulta",
					e.getMessage());

		} finally {
			return resultado;
		}
	}

}
